2 Problem: 11504 - Dominos
3 Author: Andrés Mejía-Posada
4 (http://blogaritmo.factorcomun.org)
18 vector
<int> g
[N
], gt
[N
];
19 int visited
[N
], scc
[N
], in_degree
[N
];
21 void dfs(int u
, int mark
, deque
<int> *in_order
, int visited
[], vector
<int> g
[]){
24 vector
<int> &out
= g
[u
];
25 for (int k
=0, m
=out
.size(); k
<m
; ++k
){
27 if (!visited
[v
]) dfs(v
, mark
, in_order
, visited
, g
);
29 if (in_order
) in_order
->push_front(u
);
35 int n
, m
; cin
>> n
>> m
;
37 for (int i
=0; i
<=n
; ++i
) g
[i
].clear(), gt
[i
].clear(), visited
[i
] = scc
[i
] = in_degree
[i
] = 0;
39 for (int u
, v
, i
=0; i
<m
&& cin
>> u
>> v
; ++i
) g
[u
].push_back(v
), gt
[v
].push_back(u
);
43 for (int i
=1; i
<=n
; ++i
)
45 dfs(i
, 1, &in_order
, visited
, g
);
49 for (deque
<int>::iterator i
=in_order
.begin(); i
!=in_order
.end(); ++i
)
51 dfs(*i
, id
++, NULL
, scc
, gt
);
55 for (int i=0; i<=n; ++i){
56 printf("ssc[%d] = %d\n", i, scc[i]);
62 for (int i
=1; i
<=n
; ++i
){
63 vector
<int> &out
= g
[i
];
64 for (int k
=0, m
=out
.size(); k
<m
; ++k
){
66 if (scc
[i
] != scc
[j
]) in_degree
[scc
[j
]]++;
71 for (int i
=1; i
<id
; ++i
){
72 //printf("in_degree[%d] = %d\n", i, in_degree[i]);
83 Explicación del algoritmo:
85 Lo primero es ver que cada componente fuertemente conexa del grafo puede
86 tumbarse completamente usando solo una ficha. Entonces primero reducimos
87 el grafo a un DAG donde cada nodo representa una componente fuertemente
88 conexa del grafo original.
90 La respuesta es el número de nodos en el nuevo grafo que tienen in-degree == 0.